<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>矢量瓦片过滤</title>
    <link rel="stylesheet" href="./css/bootstrap.min.css" type="text/css"/>
    <link rel="stylesheet" href="./css/ol.css" type="text/css"/>
    <link rel="stylesheet" href="./css/ktol3.css" type="text/css"/>
    <link rel="stylesheet" href="./css/mapPop.css" type="text/css"/>
    <link href="./css/pretty.css" rel="stylesheet"/>
    <script
            type="text/javascript"
            include="bootstrap,widgets.alert"
            src="./js/include-web.js"
    ></script>
    <script type="text/javascript" src="./js/jquery-1.11.2.min.js"></script>
    <script type="text/javascript" src="./js/ol-debug.js"></script>
    <!-- <script type="text/javascript" src="./js/proj4.js"></script> -->
    <script
            type="text/javascript"
            src="./js/iclient-ol-es6.js"
    ></script>
    <script type="text/javascript" src="./js/olms.js"></script>
    <script type="text/javascript" src="./js/bootstrap-treeview.js"></script>
    <style>
        .ol-popup {
            position: absolute;
            background-color: white;
            -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
            filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
            padding: 15px;
            border-radius: 10px;
            border: 1px solid #cccccc;
            bottom: 12px;
            left: -50px;
            min-width: 300px;
        }

        .ol-popup:after,
        .ol-popup:before {
            top: 100%;
            border: solid transparent;
            content: ' ';
            height: 0;
            width: 0;
            position: absolute;
            pointer-events: none;
        }

        .ol-popup:after {
            border-top-color: white;
            border-width: 10px;
            left: 48px;
            margin-left: -10px;
        }

        .ol-popup:before {
            border-top-color: #cccccc;
            border-width: 11px;
            left: 48px;
            margin-left: -11px;
        }

        .ol-popup-closer {
            text-decoration: none;
            position: absolute;
            top: 2px;
            right: 8px;
        }

        .ol-popup-closer:after {
            content: '✖';
        }

        .tooltip {
            position: relative;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 4px;
            color: white;
            padding: 4px 8px;
            opacity: 0.7;
            white-space: nowrap;
        }

        .params {
            position: fixed;
            right: 15px;
            top: 10px;
            width: 300px;
            height: 130px;
        }

        .input-group input {
            height: 100%;
            padding: 5px;
        }

        .node-bas_tree:not(.node-disabled):hover {
            background-color: unset !important;
        }
    </style>
</head>

<body
        style="
            margin: 0;
            overflow: hidden;
            background: #fff;
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
        "
>
<div id="map" style="width: 100%; height: 100%;" w></div>
<div id="info" class="ol-popup">
    <a href="#" id="popup-closer" class="ol-popup-closer"></a>
    <div id="info-content"></div>
</div>

<div id="toolbar" class="param-container tool-bar"
     style="position: absolute;margin: 10px;top:0;left: 30px;z-index: 100;">
    <div id="bas_tree"></div>
</div>
<!--<div class="panel panel-primary params">-->
<!--<div class="panel-heading">流域过滤</div>-->
<!--<div style="padding: 8px 15px;">-->
<!--<div id="bas_tree"></div>-->
<!--<input-->
<!--style="margin-top: 8px;"-->
<!--type="button"-->
<!--class="btn btn-default"-->
<!--value="过滤"-->
<!--onclick="filter()"-->
<!--/>-->
<!--</div>-->
<!--</div>-->

<script>
    // 4490坐标系需自定义
    proj4.defs('EPSG:4490', '+proj=longlat +ellps=GRS80 +no_defs')
    var projection = new ol.proj.get('EPSG:4490')
    projection.setExtent([-180, -90, 180, 90])

    // 指定此Arcgis图层的分辨率
    var resolutions = [
        0.001373291015624828,
        0.000686645507812414,
        0.000343322753906207,
        0.0001716613769531035,
        0.00008583068847655175,
        0.000042915344238275876,
        0.000021457672119137938,
        0.000010728836059568969,
        0.0000053644180297844846,
        0.0000026822090148922423,
        0.0000013411045074461211,
    ]
    var matrixIds = []
    for (var z = 0; z < resolutions.length; ++z) {
        matrixIds[z] = z
    }
    var url =
        'http://192.168.37.161/tilemap_1/rest/services/SZIMAGE/SZAVI201712_20ZW2K/ImageServer/tile/{z}/{y}/{x}'

    var view = new ol.View({
        projection: projection, //坐标系参数如果不设置，则默认为墨卡托
        resolutions: resolutions, //分辨率层级数组
        center: [114.14920825956825, 22.611386775967627],
        zoom: 1,
    })

    var map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                source: new ol.source.XYZ({
                    url: url,
                    projection: projection,
                    tileGrid: new ol.tilegrid.WMTS({
                        origin: [-180, 90],
                        tileSize: 256,
                        resolutions: resolutions,
                        matrixIds: matrixIds,
                    }),
                }),
            }),
        ],
        target: 'map',
        controls: ol.control.defaults({
            attributionOptions: {
                collapsible: false,
            },
        }),
        view: view,
    })

    var content = document.getElementById('info-content')
    var overlay = new ol.Overlay({
        element: document.getElementById('info'),
        autoPan: true,
        autoPanAnimation: {
            duration: 250,
        },
    })

    //绑定popup
    map.addOverlay(overlay)

    //添加pupop x按钮
    document.getElementById('popup-closer').onclick = function () {
        overlay.setPosition(undefined)
        this.blur()
        return false
    }

    //点击地图
    map.on('click', mapOnClickListener)

    function mapOnClickListener(e) {
        overlay.setPosition(undefined)
        var selected = false
        map.forEachFeatureAtPixel(
            e.pixel,
            function (feature) {
                var props = feature.getProperties()
                content.innerHTML =
                    '编号：' +
                    props['obj_code'] +
                    '<br>' +
                    '名称：' +
                    props['obj_name'] +
                    '<br>' +
                    '类型：' +
                    props['elementtype'] +
                    '<br>' +
                    '图层名：' +
                    props['layer']
                if (feature.getGeometry().getType() === 'Point') {
                    overlay.setPosition(
                        feature.getGeometry().getCoordinates()
                    )
                } else {
                    overlay.setPosition(e.coordinate)
                }

                selected = true
            },
            {
                hitTolerance: 10,
            }
        )
    }

    // 构建流域数据结构
    var basList = [
        {
            text: "流域列表",
            isBas: false,
            nodes: [
                {
                    text: "深圳河流域",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "深圳湾水系",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "大亚湾水系",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "龙岗河流域",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "坪山河流域",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "珠江口水系",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "观澜河流域",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "茅洲河流域",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "大鹏湾水系",
                    isBas: true,
                    state: {
                        checked: true
                    }
                },
                {
                    text: "其它",
                    isBas: false,
                    state: {
                        checked: true
                    }
                }
            ]
        }
    ];

    var nodeCheckedSilent = false;

    function nodeChecked(event, node) {
        if (nodeCheckedSilent) return;
        nodeCheckedSilent = true;
        if (node.isBas) {
            filter(node.text)
        }
        if (!node.isBas && node.text === '其它') {
            filterOther()
        }
        checkAllParent(node);
        checkAllSon(node);
        nodeCheckedSilent = false;
    }

    var nodeUncheckedSilent = false;

    function nodeUnchecked(event, node) {
        if (nodeUncheckedSilent) {
            return
        }
        nodeUncheckedSilent = true;
        if (node.isBas) {
            defilter(node.text);
        }
        if (!node.isBas && node.text === '其它') {
            defilterOther()
        }
        uncheckAllParent(node);
        uncheckAllSon(node);
        nodeUncheckedSilent = false;
    }

    //选中全部父节点
    function checkAllParent(node) {
        $('#bas_tree').treeview('checkNode', node.nodeId, {
            silent: true
        });

        var parentNode = $('#bas_tree').treeview('getParent', node.nodeId)
        if (!("nodeId" in parentNode)) {
            return;
        } else {
            checkAllParent(parentNode);
        }
    }

    //取消全部父节点
    function uncheckAllParent(node) {
        $('#bas_tree').treeview('uncheckNode', node.nodeId, {
            silent: true
        });
        var siblings = $('#bas_tree').treeview('getSiblings', node.nodeId);
        var parentNode = $('#bas_tree').treeview('getParent', node.nodeId);
        if (!("nodeId" in parentNode)) {
            return
        }
        ;
        var isAllUnchecked = true; //是否全部没选中
        for (var i in siblings) {
            if (siblings[i].state.checked) {
                isAllUnchecked = false;
                break;
            }
        }
        if (isAllUnchecked) uncheckAllParent(parentNode);
    }

    //级联选中所有子节点
    function checkAllSon(node) {
        $('#bas_tree').treeview('checkNode', node.nodeId, {
            silent: true
        });
        if (node.nodes != null && node.nodes.length > 0) {
            for (var i in node.nodes) {
                if (node.nodes[i].isBas) {
                    filter(node.nodes[i].text)
                }
                if (!node.nodes[i].isBas && node.nodes[i].text === '其它') {
                    filterOther()
                }
                checkAllSon(node.nodes[i]);
            }
        }
    }

    //级联取消所有子节点
    function uncheckAllSon(node) {
        $('#bas_tree').treeview('uncheckNode', node.nodeId, {
            silent: true
        });
        if (node.nodes != null && node.nodes.length > 0) {
            for (var i in node.nodes) {
                if (node.nodes[i].isBas) {
                    defilter(node.nodes[i].text)
                }
                if (!node.nodes[i].isBas && node.nodes[i].text === '其它') {
                    defilterOther()
                }
                uncheckAllSon(node.nodes[i]);
            }
        }
    }

    $('#bas_tree').treeview({
        showCheckbox: true,
        data: basList,
        backColor: '#000',
        onhoverColor: '#000',
        onNodeChecked: nodeChecked,
        onNodeUnchecked: nodeUnchecked
    })


    /*
    * 矢量瓦片构建添加*/
    var river_style_url = 'http://10.230.30.94:8090/iserver/services/map-mvt-szrv/restjsr/v1/vectortile/maps/sz_rv/style.json'
    var riverVt = null
    var rswb_style_url = 'http://10.230.30.94:8090/iserver/services/map-mvt-szrswb/restjsr/v1/vectortile/maps/sz_rswb/style.json'
    var rswbVt = null

    var format = new ol.format.MVT({
        featureClass: ol.Feature,
    })

    var river_style = new ol.supermap.MapboxStyles({
        style: river_style_url,
        map: map
    })
    var rswb_style = new ol.supermap.MapboxStyles({
        style: rswb_style_url,
        map: map
    })

    river_style.on('styleloaded', function () {
        for (var i = 0; i < river_style._mbStyle.layers.length; i++) {
            if (river_style._mbStyle.layers[i].hasOwnProperty('filter')) {
                river_style._mbStyle.layers[i]['defaultFilter'] = river_style._mbStyle.layers[i]['filter']
            } else {
                river_style._mbStyle.layers[i]['defaultFilter'] = null
            }
        }
        riverVt = new ol.layer.VectorTile({
            declutter: true,
            source: new ol.source.VectorTileSuperMapRest({
                style: river_style_url,
                projection: projection,
                format: format
            }),
            style: river_style.getStyleFunction()
        });
        map.addLayer(riverVt);
    })

    rswb_style.on('styleloaded', function () {
        for (var i = 0; i < rswb_style._mbStyle.layers.length; i++) {
            if (rswb_style._mbStyle.layers[i].hasOwnProperty('filter')) {
                rswb_style._mbStyle.layers[i]['defaultFilter'] = rswb_style._mbStyle.layers[i]['filter']
            } else {
                rswb_style._mbStyle.layers[i]['defaultFilter'] = null
            }
        }
        rswbVt = new ol.layer.VectorTile({
            declutter: true,
            source: new ol.source.VectorTileSuperMapRest({
                style: rswb_style_url,
                projection: projection,
                format: format
            }),
            style: rswb_style.getStyleFunction()
        });
        map.addLayer(rswbVt);
        $('#bas_tree').treeview('uncheckAll', { silent: false });
    })


    /*
    * 矢量瓦片过滤**/
    var filterCache = [];
    var filters = [];
    var noneFilters = [];

    function filter(bas_nm) {
        var _filter = createFilter('bas_nm', bas_nm);
        addFilter(_filter)
        filterStyle(river_style, riverVt);
        filterStyle(rswb_style, rswbVt);
    }

    // 其它需要视具体情况而定
    function filterOther () {
        var _filter = ['any', ['!has', 'bas_nm'], ['==', 'bas_nm', ''], ['==', 'bas_nm', null]]
        addFilter(_filter)
        filterStyle(river_style, riverVt);
        filterStyle(rswb_style, rswbVt);
    }

    function defilter(bas_nm) {
        var _filter = createFilter('bas_nm', bas_nm);
        removeFilter(_filter)
        filterStyle(river_style, riverVt);
        filterStyle(rswb_style, rswbVt);
    }

    function defilterOther () {
        var _filter = ['any', ['!has', 'bas_nm'], ['==', 'bas_nm', ''], ['==', 'bas_nm', null]]
        removeFilter(_filter)
        filterStyle(river_style, riverVt);
        filterStyle(rswb_style, rswbVt);
    }

    // 此处固定为流域名称
    function createFilter(fieldName, fieldValue) {
        return ['==', fieldName, fieldValue]
    }

    function addFilter(filterOption) {
        filters = ['any']
        if (filterCache.length === 0) {
            filterCache.push(filterOption);
            filters.push(filterOption)
        } else {
            var flag = false
            for (var i = 0; i < filterCache.length; i++) {
                if (JSON.stringify(filterOption) == JSON.stringify(filterCache[i])) { // 简单判断
                    flag = true
                } else {
                    filters.push(filterCache[i])
                }
            }
            if (!flag) {
                filterCache.push(filterOption)
                filters.push(filterOption)
            }
        }
    }

    function removeFilter(filterOption) {
        filters = []
        if (filterCache.length === 0) {
            return
        } else {
            for (var i = filterCache.length - 1; i >= 0; i--) {
                if (JSON.stringify(filterOption) == JSON.stringify(filterCache[i])) { // 简单判断
                    filterCache.splice(i, 1)
                }
            }
            for (var i = 0; i < filterCache.length; i++) {
                filters.push(filterCache[i])
            }
            if (filters.length > 0) {
                filters.unshift('any')
            }
        }
    }

    function filterStyle(style, vectorLayer) {
        var updateStyles = []
        var layers = getFilterLayers(style);
        for (var i = 0; i < layers.length; i++) {
            var _layer = layers[i]
            if (_layer.id === 'background') continue
            var layerOption = {
                id: _layer.id,
                defaultFilter: _layer.defaultFilter,
                filter: _layer.defaultFilter
            }
            if (Array.isArray(layerOption.filter)) {
                if (filters.length > 0) {
                    if (layerOption.filter[0] === 'all') {
                        layerOption.filter.push(filters);
                    } else {
                        layerOption.filter = ['all', layerOption.filter, filters]
                    }
                } else {
                    style._mbStyle.layers[i].filter = layerOption.defaultFilter
                    layerOption.filter = ['none', noneFilters];
                }
                updateStyles.push(layerOption)
            } else {
                if (filters.length > 0) {
                    layerOption.filter = filters
                } else {
                    style._mbStyle.layers[i].filter = layerOption.defaultFilter
                    layerOption.filter = ['none', noneFilters]
                }
                updateStyles.push(layerOption)
            }
        }
        style.updateStyles(updateStyles);
        vectorLayer.getSource().changed();
    }

    function getFilterLayers(style) {
        var _layers = style._mbStyle.layers
        return _layers;
    }

    function createNoneFilter () {
        var _nodes = $('#bas_tree').treeview('getEnabled');
        for (var i=0; i<_nodes.length; i++) {
            if (_nodes[i].isBas) {
                noneFilters.push(createFilter('bas_nm', _nodes[i].text))
            }
            if (!_nodes[i].isBas && _nodes[i].text === '其它') {
                noneFilters.push(['any', ['!has', 'bas_nm'], ['==', 'bas_nm', ''], ['==', 'bas_nm', null]])
            }
        }
    }

    createNoneFilter();
</script>
</body>
</html>
